/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package queryprocessing;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import queryterm.QueryTerm;

/**
 *
 * @author Zakiy Firdaus
 */
public class QueryExpansion {
    public QueryExpansion(){
        
    }
    
    public static float ORIGINAL_WEIGHT = (float) 1;
    public static float STEMMED_WEIGHT = (float) 0.5;
    public static float SYNONYM_WEIGHT = (float) 0.25;
    public static float RELATED_WEIGHT = (float) 0.25;
    public static float SPLITTED_WEIGHT = (float) 1; //dibagi n
    
    public static String getStem(String s){
        return PorterStemmer.stemmer(s);
    }
    
    /**
     * Fungsi utama query expansion
     * @param aqt
     * @return 
     */public static ArrayList<QueryTerm> expand(ArrayList<QueryTerm> aqt){
        ArrayList<QueryTerm> result = new ArrayList<QueryTerm> ();
        result = expandWithSplitted(aqt);
        result = expandWithStem(result);
        return result;
    }
     
    public static void sortListQuery(ArrayList<QueryTerm> aqt) {
        Collections.sort(aqt, new Comparator<QueryTerm>(){
            @Override
            public int compare(QueryTerm o1, QueryTerm o2) {
                return o1.getIsOneWord()==o2.getIsOneWord() ? 0 : o1.getIsOneWord() ? -1 : 1;
            }
            
        });
    }
    
    public static ArrayList<QueryTerm> expandWithStem(ArrayList<QueryTerm> aqt){
        ArrayList<QueryTerm> result = new ArrayList<QueryTerm>();
        HashMap<String, QueryTerm> hmqt = new HashMap<String, QueryTerm>();
        for(QueryTerm q : aqt){
            hmqt.put(q.getToken()+"'"+q.getField(), q);
        }
        
        for(QueryTerm qt:aqt){
            String token = qt.getToken();
            String stemmedToken = getStem(token);
            if(qt.getIsOneWord()&&!token.equals(stemmedToken)&&!stemmedToken.isEmpty()){
                QueryTerm newqt = new QueryTerm(stemmedToken, STEMMED_WEIGHT*qt.getWeight(), qt.getField(), true);
                if(hmqt.containsKey(stemmedToken+"'"+qt.getField())) {
                    newqt.setWeight(hmqt.get(stemmedToken+"'"+qt.getField()).getWeight() + newqt.getWeight());
                }
                hmqt.put(stemmedToken+"'"+newqt.getField(), newqt);
            }
        }
        Iterator it = hmqt.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry pairs = (Map.Entry) it.next();
            result.add((QueryTerm)pairs.getValue());
            it.remove();
        }
        return result;
    }
    
    public static ArrayList<QueryTerm> expandWithSplitted(ArrayList<QueryTerm> aqt){
        ArrayList<QueryTerm> result = new ArrayList<QueryTerm>();
        HashMap<String, QueryTerm> hmqt = new HashMap<String, QueryTerm>();
        for(QueryTerm q : aqt){
            hmqt.put(q.getToken()+"'"+q.getField(), q);
        }
        
        for(QueryTerm qt:aqt){
            if(!qt.getIsOneWord()){
                String token = qt.getToken();
                String[] splittedToken = token.split(" ");
                int n = splittedToken.length;
                
                for(String stoken:splittedToken){
                    if(stoken.isEmpty()){
                        
                    } else {
                        QueryTerm newqt = new QueryTerm(stoken, SPLITTED_WEIGHT/n, qt.getField(), true);
                        if(hmqt.containsKey(stoken+"'"+qt.getField())){
                            newqt.setWeight(hmqt.get(stoken+"'"+qt.getField()).getWeight()+newqt.getWeight());
                        }
                        hmqt.put(stoken+"'"+newqt.getField(), newqt);
                    }
                        
                }
                
            }
            
        }
        Iterator it = hmqt.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry pairs = (Map.Entry) it.next();
            result.add((QueryTerm)pairs.getValue());
            it.remove();
        }
        return result;
    }
    
    
}
